package vars

import org.mbari.vars.knowledgebase.model.dao.LWConceptNameDAO
import org.mbari.vars.knowledgebase.model.dao.ConceptDAO
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import vars.DAO

class AnalysisUtil {
    
    private static final log = LoggerFactory.getLogger(AnalysisUtil.class)
    
    // TODO create FlatAnnotations view that is the same as the Annotations view except it excludes Associations
    
    /**
     * Generate a histogram of all Annotations by depth for the
     * concept..
     * @param bins A list of depth bin edges
     * @param conceptName The concept to constrain by (alternate names will be included)
     * @return a Map of <Number depth, Integer count>
     */
    static histByConcept(List bins, String conceptName) {
        // Lookup Concept
        def concept = ConceptDAO.instance.findByName(conceptName)
        return histByConceptNames(bins, concept.conceptNameColl)
    }
    
    static histAll(List bins) {
        return histByConceptNames(bins)
    }
    
    /**
     * Generate a histogram of all Annotations by depth for the
     * conceptNams (strings) in the list.
     * @param bins A list of depth bin edges
     * @param conceptNames A list of conceptNames (strings) to constrain
     *      the results by
     * @return a Map of <Number depth, Integer count>
     */
    static histByConceptNames(List bins, Collection conceptNames = []) {
        
        log.debug("Running histogram on ${conceptNames.join(', ')}")
        
        def hist = [:]
        for (i in 1..<bins.size()) {
            def sql = """\
            SELECT 
                count(*) 
            FROM 
                FlatAnnotations 
            WHERE 
                Depth >= ${bins[i - 1]} AND 
                Depth < ${bins[i]}"""
                
            // Constrain by conceptNames if provided
            if (conceptNames?.size()) {
                sql += " AND ConceptName IN (${conceptNames.collect({"'${it}'"}).join(', ')})"
            }
                
            DAO.query(sql) { resultSet ->
                while (resultSet.next()) {
                    hist[bins[i]] = resultSet.getInt(1)
                }
            }
        }
        
        return hist
    }
    
}

